#include "recordpcmthread.h"
#include <QFile>
#include <QString>
#include <QDateTime>
#include "ffmpegutils.h"
#ifdef Q_OS_MACOS

#define FMT_NAME "avfoundation"
#define URL ":0"

#define RECORD_FILE_PATH "/Users/tgy/Documents/ffmpeg/audio/recode_pcm_"

#else

#define FMT_NAME "dshow"
#define URL ""
#define RECORD_FILE_PATH "/Users/tgy/Documents/ffmpeg/audio/recode_pcm_01.pcm"

#endif


RecordPCMThread::RecordPCMThread(QObject *parent) : QThread(parent){

    init();
}

RecordPCMThread::~RecordPCMThread()
{

    disconnect();
    requestInterruption();
    quit();
    wait();
    qDebug() << "RecordPCMThread destroy";
}

void RecordPCMThread::init()
{
    connect(this,&QThread::finished,this,&QThread::deleteLater);
}

void RecordPCMThread::run()
{


    AVInputFormat* inputFormat = av_find_input_format(FMT_NAME);

    if(inputFormat == nullptr) {

        qDebug() << "find input format fail";
        return;
    }
    AVFormatContext* context = nullptr;
    int format_open_input_result = avformat_open_input(&context,URL,inputFormat,nullptr);

    if(format_open_input_result != 0) {

        char buffer[1024];
        av_strerror(format_open_input_result,buffer,sizeof(buffer));
        qDebug() << "avformat_open_input fail:" << buffer;

        return;
    }



   QString audioPath(RECORD_FILE_PATH);
   audioPath += QString::number(QDateTime::currentMSecsSinceEpoch() / 1000);

   QString pcmPath(audioPath);
   pcmPath += ".pcm";

    QFile file(pcmPath);

    if(!file.open(QFile::WriteOnly)) {


        avformat_close_input(&context);
        qDebug() << RECORD_FILE_PATH << "open fail";
        return;
    }


    AVPacket packet;

    while (!isInterruptionRequested()) {

       int read_result = av_read_frame(context,&packet);

       if(read_result == 0) {

//            packet.size
          file.write((const char *)packet.data,packet.size);
       }else if(read_result == -35) {

           continue;
       }else {

           char buffer[1024];
           av_strerror(read_result,buffer,sizeof(buffer));
           qDebug() << "avformat_open_input fail:" << buffer;

           break;
       }
    }


    // 关闭文件
    file.close();

    // pcm 转 wav
//    showSpec(context);
    AVCodecParameters* params = context->streams[0]->codecpar;

    WAVHeadStructure wavHeadStructure;

    wavHeadStructure.sampleRate = params->sample_rate;
    wavHeadStructure.numChannels = params->channels;

    AVCodecID codecID = params->codec_id;
    wavHeadStructure.bitPerSample = av_get_bits_per_sample(codecID);


    if (codecID >= AV_CODEC_ID_PCM_S32LE) {

        wavHeadStructure.audioFormat = 3;
    }

    QString wavPath(audioPath);

    wavPath += ".wav";

    FFMPEGUtils::pcmTowav(wavHeadStructure,pcmPath.toUtf8().data(),wavPath.toUtf8().data());

    // 关闭 input
    avformat_close_input(&context);
}

void RecordPCMThread::showSpec(AVFormatContext *context)
{

    AVStream* stream = context->streams[0];

    AVCodecParameters* params = stream->codecpar;

    qDebug() << "采样率" << params->sample_rate;

    qDebug() << "声道数:" << params->channels;


    // AVSampleFormat
    //qDebug() << "format: " << params->format;
//    qDebug() << "样本的声道大小:" << av_get_bytes_per_sample((AVSampleFormat)params->format);

    // AVCodecID
    qDebug() << "format:" << params->codec_id;

    qDebug() << "format bits:" << (av_get_bits_per_sample(params->codec_id) >> 3);

}
